package com.nbicc.newpic.processor;

import com.nbicc.common.utils.ExceptionUtil;
import com.nbicc.common.utils.HtmlUtils;
import com.nbicc.common.utils.XmlUtils;
import com.nbicc.newpic.listener.NewsContentDeleteListenerImpl;
import com.nbicc.newpic.service.INewPicService;
import com.nbicc.news.po.NewsContent;
import com.nbicc.news.service.INewsContentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * @Author: lilingyan
 */

/**
 * 删除新闻内容时  尽可能删除关联的图片文件
 * 删除失败或残留  不影响使用   不做完整性控制
 */
@Slf4j
@Component
public class DeletePicByContentProcessor {

    @Resource(name = "NewsContentServiceImpl")
    private INewsContentService newsContentService;
    @Resource(name = "NewPicServiceImpl")
    private INewPicService newPicService;
    @Resource(name = "NewsContentDeleteListenerImpl")
    private NewsContentDeleteListenerImpl newsContentDeleteListener;

    private BlockingQueue<Number> newsIdQueue = new LinkedBlockingDeque<>();

    @PostConstruct
    private void runProcessor(){
        new Thread(() ->{
                while (true){
                    Number newId = null ;
                    try {
                        //解析新闻内容中的图片id，并从文件系统中删除
                        newId = newsIdQueue.take();
                        NewsContent newsContent = newsContentService.selectById(newId);
                        if(newsContent != null && !StringUtils.isEmpty(newsContent.getContent())){
                            Set<String> urls = HtmlUtils.imgSrcParse(newsContent.getContent());
                            Set<Number> ids = getIds(urls);
                            for (Number picId : ids) {
                                try {
                                    newPicService.deleteFile(picId);
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error(ExceptionUtil.getStackTraceInfo(e));
                    }finally {
                        try {
                            //不管是否错误，都执行用户设置的
                            newsContentDeleteListener.onComplete(newId);
                        } catch (Exception e) {
                            e.printStackTrace();
                            log.error(ExceptionUtil.getStackTraceInfo(e));
                        }
                    }
                }
            }
        ).start();
    }

    /**
     * 从url中剥离图片id
     * url最后/后的，就为图片id
     * @param urls
     * @return
     */
    private Set<Number> getIds(Set<String> urls){
        Set<Number> ids = new HashSet<>();
        for (String url : urls) {
            if(!StringUtils.isEmpty(url)){
                Number id = getId(url);
                if(!StringUtils.isEmpty(id)){
                    ids.add(id);
                }
            }
        }
        return ids;
    }

    private Number getId(String url){
        url = url.trim();
        int urlLastVar = url.lastIndexOf("/");
        if(urlLastVar > 0){
            try {
                return Long.valueOf(url.substring(urlLastVar + 1));
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
        return  null;
    }

    /**
     * 向队列放入需要删除的新闻id
     * @param id
     * @throws InterruptedException
     */
    public void putNewsId(Number id) throws InterruptedException {
        newsIdQueue.put(id);
    }

}
